#!/usr/bin/python
# coding=utf-8
import random, sys, logging, time, traceback
# from xpy3lib.utils.XUtils import XUtils
from datetime import datetime
from datetime import date
from flask import Flask, request, json, jsonify, abort, make_response
import sys, datetime, json, logging, os
import pandas as pd
import numpy as np
from scipy import fftpack

from xpy3lib.utils.XDataFrameUtils import XDataFrameUtils
from xpy3lib.XRetryableQuery import XRetryableQuery

from xpy3lib.utils import db_utils as util
from xpy3lib.XLogger import XLogger
from sicost.config import app_config


app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

profile = (sys.argv[1].split("=", 1)[-1]) if len(sys.argv) > 1 else 'dev'


@app.route('/api-model/get_info.sdo', methods=["GET", "POST"])
def test_index_1():
    response_dict = {'message': 'success---hi--prm-server'}
    return json.dumps(response_dict)


@app.route('/api-model/', methods=["GET", "POST"])
def test_index_0():
    response_dict = {'message': 'success---hi--model-server'}
    return json.dumps(response_dict)


@app.route('/api-model/request_picture.sdo', methods=["GET", "POST"])
def request_model():
    content = dict()
    response_dict = dict()

    body_dict = None
    if request.method == 'POST':
        try:
            try:
                request_json_text = request.get_data()
                body_dict = json.loads(request_json_text.decode('utf-8'))
            except Exception as e:
                body_dict = request.form.to_dict()
                # NOTE below is the pseudo code of post data fetching
                # postdata = request.form['id']
                # file = request.files['file']
        except Exception as e:
            body_dict = None
            traceback.print_exc()
    else:
        body_dict = request.args.to_dict(flat=True)

    #
    if body_dict is not None:
        try:
            # success, msg, remark, timestamp, table_1 = run_model_job(p_body_dict=body_dict)
            code, msg, content, time1, time2, time3, time4, time5, time6, time7, top, frequencyTop, rec_create_time = run_model_job(p_body_dict=body_dict)
        except Exception as e:
            code = -100
            msg = f'run_model_job_failed---with--{str(body_dict)}--{str(e)}'
            time1 = time.time()
            time2 = time1
            time3 = time1
            time4 = time1
            time5 = time1
            time6 = time1
            time7 = time1
            top = list()
            frequencyTop = list()
            rec_create_time = ''
    else:
        code = -200
        msg = 'invalid_http_request_parameters'
        time1 = time.time()
        time2 = time1
        time3 = time1
        time4 = time1
        time5 = time1
        time6 = time1
        time7 = time1
        top = list()
        frequencyTop = list()
        rec_create_time = ''
    #总耗时
    elapsed1 = time7 - time1
    #连接STS
    elapsed2 = time3 - time2
    #查询SQL数据
    elapsed3 = time4 - time3
    #关闭STS
    elapsed4 = time7 - time6
    #主体逻辑
    elapsed5 = time5 - time4
    #其他
    elapsed6 = elapsed1 - elapsed2 - elapsed3 - elapsed4 - elapsed5
    #连接存储数据库
    #上传时间
    #关闭连接

    response_dict['code'] = code
    response_dict['message'] = msg
    response_dict['rec_create_time'] = rec_create_time
    response_dict['top'] = top
    response_dict['frequencyTop'] = frequencyTop
    response_dict['content'] = content
    # response_dict['elapsed1'] = elapsed1
    # response_dict['elapsed2'] = elapsed2
    # response_dict['elapsed3'] = elapsed3
    # response_dict['elapsed4'] = elapsed4
    # response_dict['elapsed5'] = elapsed5
    # response_dict['elapsed6'] = elapsed6
    now = datetime.datetime.now()
    now_1 = now.strftime('%Y-%m-%d %H:%M:%S')
    response_dict['datetime'] = elapsed3
    return json.dumps(response_dict)
    # return bytes(json.dumps(response_dict), 'utf-8')

def run_model_job(p_body_dict):
    """

    """
    #程序开始
    time1 = time.time()
    row_data = p_body_dict
    # tag = row_data[0]['tag']
    # picType = row_data[0]['picType']
    # baseFrequency = row_data[0]['baseFrequency']
    sensor_no = row_data['sensor_no']
    picType = row_data['picType']
    motor = row_data['motor']
    if motor != '':
        motor = int(motor)
        baseFrequency = motor / 60
    else:
        baseFrequency = 0
    if picType == 'all' or picType == 'frequency':
        topMin = row_data['topMin']
        if topMin != '':
            topMinF = float(topMin)
        else:
            topMinF = 0

        topMax = row_data['topMax']
        if topMax != '':
            topMaxF = float(topMax)
            topMaxF = topMaxF * baseFrequency
        else:
            topMaxF = 1000000000000

        topCount = row_data['topCount']
        if topCount != '':
            topCountF = int(topCount)
        else:
            topCountF = 0

        frequencyTop = row_data['frequencyTop']
        if frequencyTop != '':
            frequencyTopF = '"' + frequencyTop + '"'
            frequencyTopF = frequencyTopF.replace(',', '\",\"')
            frequencyTopF = eval(frequencyTopF)
            listF = list(frequencyTopF)
        else:
            listF = list()

        frequencyTopStep = row_data['frequencyTopStep']
        if frequencyTopStep != '':
            frequencyTopStepF = int(frequencyTopStep)
        else:
            frequencyTopStepF = 0


    # baseFrequency = row_data['baseFrequency']
    # tag = 'BS_830334E01_830334E01_MOTOR_BSIDEBRG_HVIB_SPEED_WAVE'
    # picType = 'time'
    # picType = 'frequency'
    # picType = 'envelope'

    # baseFrequency = 128
    profile = 'dev'
    config = app_config[profile]
    #连接数据库开始
    time2 = time.time()

    try:
        db_conn_sts = util.getConnectionSTS(config.DB_HOST_STS2,
                                            config.DB_PORT_STS2,
                                            config.DB_DBNAME_STS2,
                                            config.DB_USER_STS2,
                                            config.DB_PASSWORD_STS2)
        # XLogger.getInstance().logger.info('connect db_conn_sts success')
    except Exception as e:
        db_conn_sts = None
        # XLogger.getInstance().logger.critical(str(e))
    if db_conn_sts is None:
        code = '-300'
        msg = '连接STS失败'
        content = ''
        time3 = time2
        time4 = time2
        time5 = time2
        time6 = time2
        time7 = time2
        top = list()
        frequencyTop = list()
        rec_create_time = ''
        return code, msg, content, time1, time2, time3, time4, time5, time6, time7, top, frequencyTop, rec_create_time
    #连接数据库成功，查询SQL数据开始
    now = datetime.datetime.now()
    start_time = now - datetime.timedelta(hours=2)
    now_1 = now.strftime('%Y-%m-%d %H:%M:%S')
    start_time_1 = start_time.strftime('%Y-%m-%d %H:%M:%S')

    time3 = time.time()
    # sql = " SELECT * FROM bgtasoemfn.t_motor_signal where tag='%s'  order by rec_create_time desc limit 1 " % (tag)
    sql = " select * from bgtmsosoec.t_motor_signal where sensor_no='%s' and rec_create_time<='%s' and rec_create_time>='%s' order by rec_create_time desc limit 1 " % (sensor_no,now_1,start_time_1)
    # sql = " select * from bgtmsosoec.t_motor_signal  order by rec_create_time desc limit 100 "
    # print(sql)
    df_1 = XRetryableQuery(p_db_conn=db_conn_sts, p_sql=sql, p_max_times=5).redo()
    success = df_1.empty is False
    if success is False:
        code = '-400'
        msg = 'STS查询为空'
        content = ''
        time4 = time3
        time5 = time3
        time6 = time3
        time7 = time3
        top = list()
        frequencyTop = list()
        rec_create_time = ''
        return code, msg, content, time1, time2, time3, time4, time5, time6, time7, top, frequencyTop, rec_create_time
    #读取SQL获取数据成功
    time4 = time.time()

    # signal_info_hz = df_1.loc[0, 'signal_info_hz']
    # signal_info_output = df_1.loc[0, 'signal_info_output']
    signal_info_output = df_1.loc[0, 'data_length']
    signal_info_hz = signal_info_output
    signal_value = df_1.loc[0, 'signal_value']
    rec_create_time = df_1.loc[0, 'rec_create_time']

    # print('the type of signal_value is %s' % (type(signal_value)))
    content = dict()
    #转换作图数据开始
    time5 = time.time()

    if picType == 'all':
        df_time = getcoordinate(p_picType='time', p_baseFrequency=baseFrequency,
                                           p_signal_info_hz=signal_info_hz, p_signal_info_output=signal_info_output,
                                           p_signal_value=signal_value)
        df_frequency = getcoordinate(p_picType='frequency', p_baseFrequency=baseFrequency,
                                p_signal_info_hz=signal_info_hz, p_signal_info_output=signal_info_output,
                                p_signal_value=signal_value)
        df_envelope = getcoordinate(p_picType='envelope', p_baseFrequency=baseFrequency,
                                     p_signal_info_hz=signal_info_hz, p_signal_info_output=signal_info_output,
                                     p_signal_value=signal_value)

        mydata_time = df_time.to_json(orient='records', force_ascii=False)
        mydata_time = eval(mydata_time)
        data_time = mydata_time
        content['data_time'] = data_time

        if topMax != '':
            dfF = df_frequency[(df_frequency['axisX'] <= topMaxF)]
        else:
            dfF = df_frequency
        dfF = dfF.reset_index(drop=True)
        mydata_frequency = dfF.to_json(orient='records', force_ascii=False)
        mydata_frequency = eval(mydata_frequency)
        data_frequency = mydata_frequency
        content['data_frequency'] = data_frequency

        # print(df_envelope.to_json(orient='records', force_ascii=False))
        mydata_envelope = df_envelope.to_json(orient='records', force_ascii=False)
        # print(mydata_envelope)
        # print('the type of mydata_envelope is %s' % (type(mydata_envelope)))
        mydata_envelope = eval(mydata_envelope)
        # print('the type of mydata_envelope is %s' % (type(mydata_envelope)))
        # print(df_envelope)
        # print('success')
        data_envelope = mydata_envelope
        content['data_envelope'] = data_envelope

        top = list()
        frequencyTop = list()
        df = df_frequency
        if topMin != '' and topMax != '':
            df_top = df[(df['axisX'] >= topMinF) & (df['axisX'] <= topMaxF)]
        elif topMin != '' and topMax == '':
            df_top = df[(df['axisX'] >= topMinF)]
        elif topMin == '' and topMax != '':
            df_top = df[(df['axisX'] <= topMaxF)]
        elif topMin == '' and topMax == '':
            df_top = df
        if topCount != '':
            df_top = df_top.sort_values(['axisY'], ascending=False)
            df_top = df_top.reset_index(drop=True)
            n = topCountF
            df_top_n = df_top.iloc[:n]
            # print(df_top_n)
            top_data = df_top_n.to_json(orient='records', force_ascii=False)
            top_data = eval(top_data)
            top = top_data
        else:
            top = list()


        if frequencyTop != '':
            for i in range(len(listF)):
                # print(listF[i])
                str = listF[i]
                # s = str[:-1]
                # s = float(s)
                s = float(str)

                # print(s)
                # sb = s * baseFrequency
                # sb = s * int(motor / 60)
                sb = int(s * (motor / 60))
                df_sb1 = df[(df['axisX'] >= sb)]
                df_sb1 = df_sb1.sort_values(['axisX'], ascending=True)
                df_sb1 = df_sb1.reset_index(drop=True)
                m = frequencyTopStepF + 1
                df_sb1_m = df_sb1.iloc[:m]
                df_sb2 = df[(df['axisX'] <= sb)]
                df_sb2 = df_sb2.sort_values(['axisX'], ascending=False)
                df_sb2 = df_sb2.reset_index(drop=True)
                df_sb2_m = df_sb2.iloc[:m]
                # df_sb0 = df[(df['axisX'] == sb)]
                df_sb = pd.concat([df_sb1_m, df_sb2_m], ignore_index=True)
                df_sb = df_sb.sort_values(['axisY'], ascending=False)
                df_sb = df_sb.reset_index(drop=True)
                # l = 1
                # df_sb_1 = df_sb1.iloc[:l]
                frequencyTop.append({'axisX': df_sb.loc[0, 'axisX'],
                                     'axisY': df_sb.loc[0, 'axisY']})
        else:
            frequencyTop = list()




    else:
        df = getcoordinate(p_picType=picType, p_baseFrequency=baseFrequency,
                                           p_signal_info_hz=signal_info_hz, p_signal_info_output=signal_info_output,
                                           p_signal_value=signal_value)
        top = list()
        frequencyTop = list()
        if picType == 'frequency':
            # top = dict()
            if topMin != '' and topMax != '':
                df_top = df[(df['axisX'] >= topMinF) & (df['axisX'] <= topMaxF)]
            elif topMin != '' and topMax == '':
                df_top = df[(df['axisX'] >= topMinF)]
            elif topMin == '' and topMax != '':
                df_top = df[(df['axisX'] <= topMaxF)]
            elif topMin == '' and topMax == '':
                df_top = df
            # df_top = df[(df['axisX'] >= topMin) & (df['axisX'] <= topMax)]
            if topMax != '':
                df = df[(df['axisX'] <= topMaxF)]
            else:
                df = df
            df = df.reset_index(drop=True)
            # df = df[(df['axisX'] <= topMax)]
            # df = df.reset_index(drop=True)
            if topCount != '':
                df_top = df_top.sort_values(['axisY'], ascending=False)
                df_top = df_top.reset_index(drop=True)
                n = topCountF
                df_top_n = df_top.iloc[:n]
                # print(df_top_n)
                top_data = df_top_n.to_json(orient='records', force_ascii=False)
                top_data = eval(top_data)
                top = top_data
            else:
                top = list()
            # print(top)
            # top5['top5'] = top_data
            if frequencyTop != '':
                for i in range(len(listF)):
                    # print(listF[i])
                    str = listF[i]
                    # s = str[:-1]
                    # s = float(s)
                    s = float(str)

                    # print(s)
                    # sb = s * baseFrequency
                    # sb = s * int(motor / 60)
                    sb = int(s * (motor / 60))
                    df_sb1 = df[(df['axisX'] >= sb)]
                    df_sb1 = df_sb1.sort_values(['axisX'], ascending=True)
                    df_sb1 = df_sb1.reset_index(drop=True)
                    m = frequencyTopStepF + 1
                    df_sb1_m = df_sb1.iloc[:m]
                    df_sb2 = df[(df['axisX'] <= sb)]
                    df_sb2 = df_sb2.sort_values(['axisX'], ascending=False)
                    df_sb2 = df_sb2.reset_index(drop=True)
                    df_sb2_m = df_sb2.iloc[:m]
                    # df_sb0 = df[(df['axisX'] == sb)]
                    df_sb = pd.concat([df_sb1_m, df_sb2_m], ignore_index=True)
                    df_sb = df_sb.sort_values(['axisY'], ascending=False)
                    df_sb = df_sb.reset_index(drop=True)
                    # l = 1
                    # df_sb_1 = df_sb1.iloc[:l]
                    frequencyTop.append({'axisX': df_sb.loc[0, 'axisX'],
                                         'axisY': df_sb.loc[0, 'axisY']})
            else:
                frequencyTop = list()




            # for i in range(len(listF)):
            #     # print(listF[i])
            #     str = listF[i]
            #     # s = str[:-1]
            #     # s = float(s)
            #     s = float(str)
            #     # print(s)
            #     sb = s * baseFrequency
            #     sb = s * int( motor / 60)
            #     df_sb1 = df[(df['axisX'] >= sb)]
            #     df_sb1 = df_sb1.sort_values(['axisX'], ascending=True)
            #     df_sb1 = df_sb1.reset_index(drop=True)
            #     m = frequencyTopStep+1
            #     df_sb1_m = df_sb1.iloc[:m]
            #     df_sb2 = df[(df['axisX'] <= sb)]
            #     df_sb2 = df_sb2.sort_values(['axisX'], ascending=False)
            #     df_sb2 = df_sb2.reset_index(drop=True)
            #     df_sb2_m = df_sb2.iloc[:m]
            #     # df_sb0 = df[(df['axisX'] == sb)]
            #     df_sb = pd.concat([df_sb1_m, df_sb2_m], ignore_index=True)
            #     df_sb = df_sb.sort_values(['axisY'], ascending=False)
            #     df_sb = df_sb.reset_index(drop=True)
            #     # l = 1
            #     # df_sb_1 = df_sb1.iloc[:l]
            #     frequencyTop.append({'axisX': df_sb.loc[0,'axisX'],
            #                             'axisY': df_sb.loc[0,'axisY']})
            #     # print(i)

        mydate = df.to_json(orient='records', force_ascii=False)
        # print(mydate)
        # print('the type of mydate is %s' % (type(mydate)))
        mydate = eval(mydate)
        # print('the type of mydate is %s' % (type(mydate)))
        # print(df)
        # print('success')
        data = mydate
        content['data'] = data



    #作图数据生成完成
    time6 = time.time()


    code = 0
    msg = 'ok'

    util.closeConnection(db_conn_sts)
    #关闭数据库完成
    # time7 = datetime.datetime.now()
    time7 = time.time()

    return code, msg, content, time1, time2, time3, time4, time5, time6, time7, top, frequencyTop, rec_create_time


def getcoordinate(p_picType, p_baseFrequency, p_signal_info_hz, p_signal_info_output, p_signal_value):
    p_signal_value = eval(p_signal_value)

    x = [float(v) for v in p_signal_value]
    # print("共有%d点数据" % (len(x)))
    sampling_rate = p_signal_info_hz  # 取样频率(来自传感器说明书)
    fft_size = p_signal_info_output  # FFT处理的数据样本数
    xt = np.asarray(x)
    xt = xt - np.mean(xt)  # 去直流分量
    # p_picType = 'time'
    if p_picType == 'time':
        tstemp = np.linspace(0, int(1e6 / sampling_rate * fft_size), fft_size) / 1e3
        # pl.figure(figsize=(14, 8))
        # pl.title("时间趋势图")
        # pl.ylabel("冲击平均值")
        # pl.xlabel("时间(单位ms)")
        # pl.plot(tstemp, xt)
        # pl.show()
        # list_x = xt.tolist()
        # print('the type of list_x is %s' % (type(list_x)))
        # 下一行注释掉，横坐标为时间ms，否则为数字标号
        # tstemp = np.arange(len(xt))
        # list_time = tstemp.tolist()
        # abscissa = list_time
        # abscissa = ",".join('%s' % id for id in abscissa)
        # ordinate = list_x
        # ordinate = ",".join('%s' % id for id in ordinate)
        arr3 = np.vstack((tstemp, xt))
        arr3t = arr3.T
        df = pd.DataFrame(arr3t, columns=['axisX', 'axisY'])
    if p_picType == 'frequency':
        am = np.fft.fft(xt)  # 对希尔伯特变换后的at做fft变换获得幅值
        am = np.abs(am)  # 对幅值求绝对值（此时的绝对值很大）
        am = am / len(am) * 2
        # am = am / p_signal_info_output * 2
        am = am[0: int(len(am) / 2)]
        freq = np.fft.fftfreq(len(xt), d=1 / sampling_rate)  # 获取fft频率，此时包括正频率和负频率
        freq = freq[0:int(len(freq) / 2)]  # 获取正频率
        # freq = freq / p_baseFrequency
        # m = 3
        # n = int((fft_size / 2) * p_baseFrequency / (sampling_rate / 2) * m) + 1
        # freq = freq[:n]
        # am = am[:n]

        # pl.figure(figsize=(14, 8))
        # pl.title("频域图")
        # pl.ylabel("振幅")
        # pl.xlabel("倍频")
        # pl.plot(freq, am)
        # pl.show()
        # abscissa = freq.tolist()
        # abscissa = ",".join('%s' % id for id in abscissa)
        # ordinate = am.tolist()
        # ordinate = ",".join('%s' % id for id in ordinate)
        arr3 = np.vstack((freq, am))
        arr3t = arr3.T
        df = pd.DataFrame(arr3t, columns=['axisX', 'axisY'])
        # 是否加窗
        # def hanning(M=500):
        #     # 汉宁窗
        #     windows = np.array([0.5 - 0.5 * np.cos(2 * np.pi * i / (M - 1)) for i in range(M)])
        #     return windows
        # hn = xt * hanning(M=len(xt))
        # # hn = xt
        # hnfft = np.fft.rfft(hn)
        # freqs = np.linspace(0, int(sampling_rate / 2), int(fft_size / 2 + 1))
        # print(freqs)
        # freqs = freqs / p_baseFrequency
        # n = int((fft_size / 2) * p_baseFrequency / (sampling_rate / 2) * 3) + 1
        # freqs = freqs[:n]
        # abs_hnfft = abs(hnfft)
        # abs_hnfft = abs_hnfft / fft_size * 2
        # # abs_hnfft = abs_hnfft / len(abs_hnfft) * 2
        # abs_hnfft = abs_hnfft[:n]
        # pl.figure(figsize=(14, 8))
        # pl.title("频域图")
        # pl.ylabel("振幅")
        # pl.xlabel("倍频")
        # pl.plot(freqs, abs_hnfft)
        # pl.show()
        # abscissa = freqs.tolist()
        # abscissa = ",".join('%s' % id for id in abscissa)
        # ordinate = abs_hnfft.tolist()
        # ordinate = ",".join('%s' % id for id in ordinate)
    if p_picType == 'envelope':
        # xt = np.asarray(x)
        ht = fftpack.hilbert(xt)
        # print(ht)
        at = np.sqrt(ht ** 2 + xt ** 2)  # at = sqrt(xt^2 + ht^2)
        sampling_rate = sampling_rate
        at = at - np.mean(at)  # 去直流分量
        am = np.fft.fft(at)  # 对希尔伯特变换后的at做fft变换获得幅值
        am = np.abs(am)  # 对幅值求绝对值（此时的绝对值很大）
        am = am / len(am) * 2
        am = am[0: int(len(am) / 2)]
        freq = np.fft.fftfreq(len(at), d=1 / sampling_rate)  # 获取fft频率，此时包括正频率和负频率
        freq = freq[0:int(len(freq) / 2)]  # 获取正频率
        # freq = freq / p_baseFrequency
        # m = 3
        # n = int((fft_size / 2) * p_baseFrequency / (sampling_rate / 2) * m) + 1
        # freq = freq[:n]
        # am = am[:n]

        # pl.figure(figsize=(14, 8))
        # pl.title("包络图")
        # pl.ylabel("希尔伯特变换后幅值")
        # pl.xlabel("倍频")
        # pl.plot(freq, am)
        # pl.show()
        # abscissa = freq.tolist()
        # abscissa = ",".join('%s' % id for id in abscissa)
        # ordinate = am.tolist()
        # ordinate = ",".join('%s' % id for id in ordinate)
        arr3 = np.vstack((freq, am))
        arr3t = arr3.T
        df = pd.DataFrame(arr3t, columns=['axisX', 'axisY'])
    return df


if __name__ == '__main__':
    # exeutors = {
    #     "default": ProcessPoolExecutor(max_workers=10)
    # }
    # app.scheduler = BackgroundScheduler(exeutors=exeutors)
    # app.scheduler.add_job(run_model_job, 'interval', seconds=3,
    #                       args=[config, '20211020000000VER', 1], id='zgh')
    # app.scheduler.start()

    # NOTE
    app.run(host='0.0.0.0', port=7078)
